/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package la.foton.homebroker.negocio.entidade;

import java.math.BigDecimal;
import java.util.Date;

import la.foton.homebroker.negocio.entidade.enumeracoes.EstadoExecucaoOrdem;
import la.foton.homebroker.negocio.entidade.enumeracoes.TipoOperacao;
import la.foton.homebroker.negocio.validador.Validador;
import la.foton.homebroker.negocio.validador.ViolacaoNegocioException;
import la.foton.homebroker.negocio.validador.obrigatoriedade.Obrigatorio;

/**
 * @author luiz
 */
public class Ordem {

	@Obrigatorio
	private Acao acao;
	@Obrigatorio
	private TipoOperacao tipoOperacao;

	private int quantidadeSolicitada;
	@Obrigatorio
	private BigDecimal preco;
	@Obrigatorio
	private Date dataPregao;

	private EstadoExecucaoOrdem estadoExecucaoOrdem;

	private int quantidadeExecutada;

	public void valida(Cotacao cotacao) throws ViolacaoNegocioException {
		acao.valida();
		cotacao.valida();
		Validador.valida(this);
		validaLotePadrao(cotacao);
	}

	private void validaLotePadrao(Cotacao cotacao)
			throws ViolacaoNegocioException {
		if (quantidadeSolicitada % cotacao.getAcao().getLotePadrao() != 0)
			throw new ViolacaoNegocioException(
					"Quantidade de ações não corresponde ao lote padrão");
	}

	public Acao getAcao() {
		return acao;
	}

	public void setAcao(Acao acao) {
		this.acao = acao;
	}

	public TipoOperacao getTipoOperacao() {
		return tipoOperacao;
	}

	public void setTipoOperacao(TipoOperacao tipoOperacao) {
		this.tipoOperacao = tipoOperacao;
	}

	public int getQuantidadeSolicitada() {
		return quantidadeSolicitada;
	}

	public void setQuantidadeSolicitada(int quantidadeSolicitada) {
		this.quantidadeSolicitada = quantidadeSolicitada;
	}

	public BigDecimal getPreco() {
		return preco;
	}

	public void setPreco(BigDecimal preco) {
		this.preco = preco;
	}

	public Date getDataPregao() {
		return dataPregao;
	}

	public void setDataPregao(Date dataPregao) {
		this.dataPregao = dataPregao;
	}

	public EstadoExecucaoOrdem getEstadoExecucaoOrdem() {
		return estadoExecucaoOrdem;
	}

	public void setEstadoExecucaoOrdem(EstadoExecucaoOrdem estadoExecucaoOrdem) {
		this.estadoExecucaoOrdem = estadoExecucaoOrdem;
	}

	public BigDecimal getValorFinanceiroSolicitado() {
		return preco.multiply(BigDecimal.valueOf(quantidadeSolicitada));
	}

	public BigDecimal getValorFinanceiroExecutado() {
		return preco.multiply(BigDecimal.valueOf(getQuantidadeExecutada()));
	}

	public BigDecimal getTaxaCorretagem(BigDecimal valorFinanceiro) {
		return valorFinanceiro.divide(new BigDecimal("100"));
	}

	public void registraQuantidadeExecutada(int quantidadeExecutada)
			throws ViolacaoNegocioException {
		if (quantidadeExecutada > quantidadeSolicitada)
			throw new ViolacaoNegocioException("Quantidade inválida");

		this.setQuantidadeExecutada(this.getQuantidadeExecutada()
				+ quantidadeExecutada);

		if (quantidadeExecutada == 0) {
			estadoExecucaoOrdem = EstadoExecucaoOrdem.PENDENTE;
		} else if (quantidadeExecutada == quantidadeSolicitada) {
			estadoExecucaoOrdem = EstadoExecucaoOrdem.TOTALMENTE;
		} else {
			estadoExecucaoOrdem = EstadoExecucaoOrdem.PARCIALMENTE;
		}
	}

	public int getQuantidadeExecutada() {
		return quantidadeExecutada;
	}

	public void setQuantidadeExecutada(int quantidadeExecutada) {
		this.quantidadeExecutada = quantidadeExecutada;
	}

}
